package com.vcc.boss.controller;


import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.mybatisflex.core.paginate.Page;
import com.vcc.core.annotations.RestPack;
import com.vcc.core.exception.ProgramException;
import com.vcc.core.util.RedisCustomizeUtils;
import com.vcc.data.entity.ClientPermission;
import com.vcc.data.entity.ClientRolePermission;
import com.vcc.data.entity.Role;
import com.vcc.service.boss.request.clientRole.BossClientRoleCreateRequest;
import com.vcc.service.boss.request.clientRole.BossClientRoleUpdateRequest;
import com.vcc.service.boss.response.clientRole.ClientPermissionVoBoss;
import com.vcc.service.boss.response.clientRole.ClientRoleVoBoss;
import com.vcc.service.sa.BossUserUtil;
import com.vcc.service.service.*;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@RestController
@RequestMapping("/client/role")
public class ClientRoleController {

    @Resource
    private RoleService roleService;

    @Resource
    private ClientRolePermissionService clientRolePermissionService;

    @Resource
    private ClientPermissionService clientPermissionService;
    @Resource
    private UserService userService;
    @Resource
    private UserRoleService userRoleService;


    @RestPack
    @SaCheckPermission(value = "client:role:list:view")
    @GetMapping("/paging")
    public Page<ClientRoleVoBoss> paging(Long pageNumber, Long pageSize, Long targetUserId, String code, String name) {
        if (targetUserId != null && targetUserId != 0L) {
            Long dealerId = userService.getDealerIdById(targetUserId);
            if (!BossUserUtil.hasAllData() && !dealerId.equals(BossUserUtil.getId())) {
                throw new ProgramException("无权查看该用户的参数配置");
            }
        }
        return roleService.paging(new Page<>(pageNumber, pageSize), targetUserId, code, name).map(
                it -> {
                    List<ClientPermission> clientPermissions = clientPermissionService.listByRoleId(it.getId());
                    //根据父子关系进行分组
                    ArrayList<ClientPermissionVoBoss> clientPermissionVos = new ArrayList<>();
                    List<ClientPermission> parentId = clientPermissions.stream().filter(ClientPermission::getHasParent).toList();
                    for (ClientPermission clientPermission : parentId) {
                        ClientPermissionVoBoss clientPermissionVo = new ClientPermissionVoBoss(clientPermission);
                        List<ClientPermissionVoBoss> children = clientPermissions
                                .stream()
                                .filter(temp -> temp.getParentId().equals(clientPermission.getId()))
                                .map(ClientPermissionVoBoss::new)
                                .toList();
                        clientPermissionVo.setChildren(children);
                        clientPermissionVos.add(clientPermissionVo);
                    }
                    it.setPermissionVos(clientPermissionVos);
                    return it;
                }
        );
    }


    @RestPack
    @SaCheckPermission(value = "client:role:list:create")
    @PostMapping("/add")
    public Boolean add(@RequestBody BossClientRoleCreateRequest bossClientRoleCreateRequest) {
        if (bossClientRoleCreateRequest.getHasClientIntoRole()) {
            if (roleService.existsByHasClientIntoRole(bossClientRoleCreateRequest.getHasClientIntoRole())) {
                throw new ProgramException("已经存在初始化角色无法再次创建");
            }
        }
        if (roleService.existsByCodeAndUserId(bossClientRoleCreateRequest.getCode(), bossClientRoleCreateRequest.getUserId())) {
            throw new ProgramException("角色编码已存在");
        }
        if (roleService.existsByNameAndUserId(bossClientRoleCreateRequest.getName(), bossClientRoleCreateRequest.getUserId())) {
            throw new ProgramException("角色名称已存在");
        }
        if (bossClientRoleCreateRequest.getPermissionVos() == null && bossClientRoleCreateRequest.getPermissionVos().isEmpty()) {
            throw new ProgramException("权限不能为空");
        }
        Role role = new Role();
        role.setCode(bossClientRoleCreateRequest.getCode());
        role.setName(bossClientRoleCreateRequest.getName());
        role.setStatus(0);
        role.setHasClientIntoRole(bossClientRoleCreateRequest.getHasClientIntoRole());
        role.setHasClientUpdate(bossClientRoleCreateRequest.getHasClientUpdate());
        role.setHasAllData(bossClientRoleCreateRequest.getHasAllData());
        role.setUserId(bossClientRoleCreateRequest.getHasClientIntoRole() ? 0 : bossClientRoleCreateRequest.getUserId());
        roleService.save(role);
        Set<Long> clientRolePermissions = new HashSet<>();
        bossClientRoleCreateRequest.getPermissionVos().forEach(it -> {
            ClientPermission clientPermission = clientPermissionService.getByIdOpt(it).orElseThrow(() -> new ProgramException("权限不存在"));
            if (clientPermission.getHasParent()) {
                clientRolePermissions.addAll(clientPermissionService.listIdsByParentId(clientPermission.getId()));
            } else {
                clientRolePermissions.add(clientPermission.getId());
                clientRolePermissions.add(clientPermission.getParentId());
            }
        });
        clientRolePermissionService.deleteByRoleId(role.getId());
        clientRolePermissions.forEach(it -> {
            ClientRolePermission clientRolePermission = new ClientRolePermission();
            clientRolePermission.setRoleId(role.getId());
            clientRolePermission.setPermissionId(it);
            clientRolePermission.setStatus(0);
            clientRolePermissionService.save(clientRolePermission);
        });
        return true;
    }

    @RestPack
    @SaCheckPermission(value = "client:role:list:edit")
    @SaCheckLogin
    @PostMapping("/update")
    public Boolean update(@RequestBody @Validated BossClientRoleUpdateRequest bossClientRoleUpdateRequest) {
        Long dealerId = userService.getDealerIdById(bossClientRoleUpdateRequest.getUserId());
        if (!BossUserUtil.hasAllData() && !dealerId.equals(BossUserUtil.getId())) {
            throw new ProgramException("无权查看该用户的参数配置");
        }
        roleService.updateRole(bossClientRoleUpdateRequest);
        Set<Long> clientRolePermissions = new HashSet<>();
        bossClientRoleUpdateRequest.getPermissionVos().forEach(it -> {
            ClientPermission clientPermission = clientPermissionService.getByIdOpt(it).orElseThrow(() -> new ProgramException("权限不存在"));
            if (clientPermission.getHasParent()) {
                clientRolePermissions.addAll(clientPermissionService.listIdsByParentId(clientPermission.getId()));
            } else {
                clientRolePermissions.add(clientPermission.getId());
                clientRolePermissions.add(clientPermission.getParentId());
            }
        });
        clientRolePermissionService.deleteByRoleId(bossClientRoleUpdateRequest.getId());
        clientRolePermissions.forEach(it -> {
            ClientRolePermission clientRolePermission = new ClientRolePermission();
            clientRolePermission.setRoleId(bossClientRoleUpdateRequest.getId());
            clientRolePermission.setPermissionId(it);
            clientRolePermission.setStatus(0);
            clientRolePermissionService.save(clientRolePermission);
        });
        List<String> keys = userRoleService.listUserIdByRoleId(bossClientRoleUpdateRequest.getId()).stream().map(it -> "user_client_permission:" + it).toList();
        if (!keys.isEmpty()) {
            RedisCustomizeUtils.removeKeys(keys);
        }
        return true;
    }

}
